package agngui.ui;

import javax.swing.*;

import agngui.tools.Converter;
import agngui.tools.SpringUtilities;
import agngui.tools.UNIT_TYPE;

import java.awt.*;
import java.awt.event.*;
import java.util.HashMap;
import java.util.Map;

/**
 * 
 * This class provides a simple UI-based tool for performing fast unit conversions across
 * multiple different units of the same type.
 * 
 * @author Ben Bloom
 * @author Phil Johnson
 */
public class ConversionWindow {

	/**
	 * The singleton instance of the converter
	 */
	private static ConversionWindow instance = new ConversionWindow();
	
	/**
	 * @return Shows and returns a handle to the singleton instance of the converter
	 */
	public static ConversionWindow getInstance() {
		instance.window.setVisible(true);
		return instance; 
	}
	
	
	/**
	 * the container for the conversion window
	 */
	private JFrame window;
	
	/**
	 * the tabbed pane that contains the various to/from mappings for conversions
	 */
	private JTabbedPane main_pane;
	
	/**
	 * a relationship between a UNIT_TYPE and all the fields that use that UNIT_TYPE
	 */
	private Map<UNIT_TYPE, JTextField[]> type_map;

	/**
	 * constructs a new ConversionWindow.  There should only ever be one of these, thus
	 * the constructor is private.  Use the getInstance() method to grab the instance of this object.
	 */
	private ConversionWindow() {
		window = new JFrame("Unit Conversion");
		window.setSize(500,500);
		main_pane = new JTabbedPane();
		Container cpane = window.getContentPane();
		type_map = new HashMap<UNIT_TYPE, JTextField[]>();
		generate();
		
		cpane.add(main_pane);
		window.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
	}
	
	/**
	 * generates the tabs and panels for the unit conversion tool
	 */
	private void generate() {
		KeyListener key_listener = new KeyAdapter() {
			public void keyPressed(KeyEvent e) {
				if(e.getKeyCode() == KeyEvent.VK_ENTER) {
					JTextField source_field = (JTextField)e.getSource();
					String from_unit = source_field.getName();
					JTextField[] group_fields = type_map.get(Field.getType(from_unit));
					try {
						double from_value = Double.parseDouble(source_field.getText());
						for(JTextField field : group_fields) {
							String to_unit = field.getName();
							double converted = Converter.convertUnits(from_value, from_unit, to_unit);
							field.setText(Double.toString(converted));
						}
					} catch(NumberFormatException nfe) {
						error(from_unit + "  contains an invalid value of \"" + source_field.getText() + "\"");
					}
				}
			}
		};
		
		
		for(String[] arr : Field.unit_strings) {
			JPanel panel = new JPanel(new SpringLayout());
			JTextField[] fields = new JTextField[arr.length-1];
			type_map.put(Field.getType(arr[0]), fields);
			for(int i = 1; i < arr.length; i++) {//the first index is the name of the type
				fields[i-1] = new JTextField(18);
				fields[i-1].setName(arr[i]);
				JLabel label = new JLabel(arr[i]);
				label.setLabelFor(fields[i-1]);
				panel.add(label);
				panel.add(fields[i-1]);
				fields[i-1].addKeyListener(key_listener);
			}
			SpringUtilities.makeCompactGrid(panel, fields.length, 2, 0, 0, 10, 10);
			main_pane.addTab(arr[0], panel);
		}
	}
	
	/**
     * displays a dialog alert box with the given message
     * @param message The message to display
     */
	private void error(String message) {
		JOptionPane.showMessageDialog(window, message, "Error!", JOptionPane.ERROR_MESSAGE);
	}
}
